//
// Created by liuml on 2018/10/19.
//

#ifndef XYMUSIC_XYAUDIO_H
#define XYMUSIC_XYAUDIO_H

#include "XYQueue.h"
#include "XYPlayStatus.h"
#include "XYCallJava.h"
#include "SoundTouch.h"

using namespace soundtouch;

extern "C" {
#include <libavcodec/avcodec.h>
#include <libswresample/swresample.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <libavutil/time.h>
};

class XYAudio {
public:
    int streamIndex = -1;

    AVCodecParameters *codecpar = NULL;
    AVCodecContext *avCodecContext = NULL;

    XYQueue *queue = NULL;
    XYPlayStatus *playStatus = NULL;
    XYCallJava *callJava = NULL;

    pthread_t thread_play;

    AVPacket *avPacket = NULL;
    AVFrame *avFrame = NULL;
    int ret = -1;
    uint8_t *buffer = NULL;//重采样放入的buffer
    int data_size = 0;
    int sample_rate = 0;// 采样率

    int duration = 0; //时间的总长度

    AVRational time_base;//时间的刻度
    double now_time = 0;//当前的时间
    double clock = 0;
    double last_time = 0;//用于避免过度调用 需要判断个差值  上一次调用的时间

    int volumePercent = 100;//默认的声音
    int mute = 2;//默认声道

    float pitch = 1.0f;
    float speed = 1.0f;

    bool idRecordPcm = false;//是否在录制

    // 引擎接口
    SLObjectItf engineObject = NULL;
    SLEngineItf engineEngine = NULL;

    //混音器
    SLObjectItf outputMixObject = NULL;
    SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
    SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;

    //pcm
    SLObjectItf pcmPlayerObject = NULL;
    SLPlayItf pcmPlayerPlay = NULL;
    //声道
    SLMuteSoloItf pcmPlayerMute = NULL;

    //音量
    SLVolumeItf pcmPlayerVolume = NULL;

    //缓冲器队列接口
    SLAndroidSimpleBufferQueueItf pcmBufferQueue = NULL;

    //SoundTouch 使用命名空间后就可以使用
    SoundTouch *soundTouch = NULL;
    SAMPLETYPE *sampleBuffer = NULL;
    //用于判断soundtouch循环是否完成
    bool finished = true;
    //用于pcm的buffer
    uint8_t *out_buffer = NULL;
    int nb = 0;//采样个数
    int num = 0;//返回的采样个数

    //判断是否录制中
    bool isRecordPcm = false;
    //一个avpackt中可能有多个avframe 需要做个判断 吧avframe读完才读取下一个avpacket
    bool readFrameFinshed = true;

    bool isCat = false;//是否开启裁剪功能
    int end_time = 0;
    bool showPcm = false;

    pthread_t pcmCallBackThread;
    int defaultPcmSize = 4096;//默认的PCM的大小


public:
    XYAudio(XYPlayStatus *playStatus, int sample_rate, XYCallJava *callJava);

    ~XYAudio();

    void play();

    //重采样
    int resampleAudio(void **pcmbuff);

    void initOpenSLES();

    int getCurrentSampleRateForOpensles(int sample_rate);

    void pause();

    void resume();

    void stop();

    void release();//回收资源

    void setVolmue(int percent);

    void setMute(int mute);//设置声道

    int getSoundTouchData();//获取soundtouch数据

    void setPitch(float pitch);//设置音调

    void setSpeed(float speed);//设置速度

    int getPCMDB(char *pcmcata, size_t pcmsize);//获取pcm分贝值

    void startStopRecord(bool start);//录制和停止录制的开关

};

#endif //XYMUSIC_XYAUDIO_H
